#include "menu_sys.h"

using namespace std;

//the path where the dishes.txt stores
const static QString g_pic_path(QT_TR_NOOP("/opt/FriendlyARM/mini2440/x86-qtopia/menu_sys/pic/"));
const static QString g_dish_path(QT_TR_NOOP("/opt/FriendlyARM/mini2440/x86-qtopia/menu_sys/dish.txt"));

menu_sys::menu_sys( QWidget* parent, const char* name, WFlags fl)
	:menu(parent,name,fl),total_price(0),ptransfer(NULL)
	,pcodec(QTextCodec::codecForName("utf-8"))//utf-8 encoding
{
	//if initialization failed,close the form
	//initialize all labels
	if(!this->init_labels())
	{
		//display message
		//add code here
		this->close();
	}
	//initialize all buttons
	if(!this->init_buttons())
	{
		//display message
		//add code here
		this->close();
	}	
	//initialize var this->dishes
	if(!this->init_dishes())
	{
		//display message
		//add code here
		this->close();
	}
	//initialize var this->desk_no
	if(!this->init_desk_no())
	{
		//display message
		//add code here
		this->close();
	}
	//initialize var this->ptransfer
	if(!this->init_ptransfer())
	{
		//display message
		//add code here
		this->close();
	}
	//just for testing messagebox
	//messagebox("初始化成功");
}

menu_sys::~menu_sys()
{
	int i;

	//free memory
	for(i=0;i<(int)dishes.size();i++)
	{
		delete dishes[i];
		dishes[i] = NULL;
	}
	//free data_transfer
	if(ptransfer != NULL)
	{
		delete ptransfer;
		ptransfer = NULL;
	}
}

//get the index of dish in varialbe dishes by dish number
int menu_sys::dish_index(int dish_no)
{
	int i;

	for(i=0;i<(int)dishes.size();i++)
	{
		if(dishes[i]->getNo() == dish_no)
			break;
	}
	//dish no doesn't exist
	if(i == (int)dishes.size())
		return -1;
	else//return the index
		return i;
}

//init all labels in forms
bool menu_sys::init_labels()
{
	QCString qcstr;
	QString qstr;

	//init TLname
	qcstr = "菜名";
	qstr = pcodec->toUnicode(qcstr);
	TLname->setText(qstr);
	//init TLwhere
	qcstr = "菜系";
	qstr = pcodec->toUnicode(qcstr);
	TLwhere->setText(qstr);
	//init TLfeature
	qcstr = "特点";
	qstr = pcodec->toUnicode(qcstr);
	TLfeature->setText(qstr);
	//init TLmix
	qcstr = "配料";
	qstr = pcodec->toUnicode(qcstr);
	TLmix->setText(qstr);
	//init TLselected
	qcstr = "已点菜";
	qstr = pcodec->toUnicode(qcstr);
	TLselected->setText(qstr);
	//init TLtotalprice
	qcstr = "总价";
	qstr = pcodec->toUnicode(qcstr);
	TLtotalprice->setText(qstr);

	return true;
}

//init all buttons in forms
bool menu_sys::init_buttons()
{
	QCString qcstr;
	QString qstr;

	//init PBselect
	qcstr = "选择";
	qstr = pcodec->toUnicode(qcstr);
	PBselect->setText(qstr);
	//init PBconfirm
	qcstr = "点菜完成";
	qstr = pcodec->toUnicode(qcstr);
	PBconfirm->setText(qstr);
	//init PBdelet
	qcstr = "删除已选菜";
	qstr = pcodec->toUnicode(qcstr);
	PBdelet->setText(qstr);
	//init PBclear
	qcstr = "清楚所有已选菜";
	qstr = pcodec->toUnicode(qcstr);
	PBclear->setText(qstr);
	//init PBclose
	qcstr = "关闭";
	qstr = pcodec->toUnicode(qcstr);
	PBclose->setText(qstr);

	return true;
}

//initialize var this->dishes from dishes.txt
//path of dishes.txt = g_pic_path
//return true if initialize success,else return false
bool menu_sys::init_dishes()
{
	int i=0;
	QString filename(g_dish_path);
	QString qstrbuf;
	QFile qfile(filename);
	QTextStream qstream;

	//if file can not be opened
	if(!qfile.open(IO_ReadOnly))
		return false;

	//set the text stream
	qstream.setDevice(&qfile);
	qstream.setCodec(pcodec);

	//read file
	while(1)
	{
		qstrbuf = qstream.readLine();
		//end of file
		if(qstrbuf.at(0) == QChar('*'))
			break;

		dishes.push_back(new dish());
		//read the number of the dish
		qstrbuf = qstream.readLine();
		dishes[i]->setNo(qstrbuf.toInt());
		//read the name of the dish
		qstrbuf = qstream.readLine();
		dishes[i]->setName(qstrbuf);
		//read the type of the dish
		qstrbuf = qstream.readLine();
		dishes[i]->setType(qstrbuf);
		//read the feature of the dish
		qstrbuf = qstream.readLine();
		dishes[i]->setFeature(qstrbuf);
		//read the mix of the dish
		qstrbuf = qstream.readLine();
		dishes[i]->setMix(qstrbuf);
		//set the picture name of the dish
		qstrbuf = qstream.readLine();
		dishes[i]->setPicname(qstrbuf);
		//set the price of the dish
		qstrbuf = qstream.readLine();
		dishes[i]->setPrice(qstrbuf.toFloat());

		i++;
	}  
	//close the file
	qfile.close();

	QIconViewItem * item = NULL;
	QString pic_path;
	//initialize items of IVdishlist
	for(i=0;i<(int)dishes.size();i++)
    	{
		item=new QIconViewItem(IVdishlist);
		pic_path = g_pic_path+dishes[i]->getPicname()+tr("1.png");
		item->setPixmap(QPixmap(pic_path,"png"));
		item->setText(dishes[i]->getName());
	}

	//initialize IconView IVpicture
	item = NULL;
	pic_path = g_pic_path+dishes[0]->getPicname()+tr(".png");
	item = new QIconViewItem(IVpicture);
	IVpicture->firstItem()->setPixmap(QPixmap(pic_path,"png"));

	//initialize the text of TVtotalprice
	TVtotalprice->setText(tr("0.00"));
	IVdishlist->setCurrentItem(IVdishlist->firstItem());

	return true;
}

//initilize var this->desk_no from a file or in some other way
//return true if initialize success,else return false
bool menu_sys::init_desk_no()
{
	//add code here
	//temporarily***************************
	desk_no=1;
	return true;
}

//init var ptransfer
bool menu_sys::init_ptransfer()
{
	ptransfer = new secure_transfer();

	if(ptransfer->is_open())
		return true;
	else
		return false;
}

//display a messagebox containing hint message with an OK button
//param message is the message you want to display
//param message should use utf-8 encoding
void menu_sys::messagebox(const char* message)
{
	QCString qccaption = "提示";
	QCString qctext = message;
	QCString qcok = "确定";
	//construct a messagebox
	QMessageBox box(pcodec->toUnicode(qccaption),//caption of the messagebox
						pcodec->toUnicode(qctext),//text displayed in the messagebox
						QMessageBox::NoIcon,//don't use icon
						QMessageBox::Ok|QMessageBox::Default,//button0:ok button
						QMessageBox::NoButton,QMessageBox::NoButton,//button1 and button2
						this,"Hint");
	//set the text of the ok button
	box.setButtonText(QMessageBox::Ok,pcodec->toUnicode(qcok));
	box.exec();
}

//when the customer selected a different dish's picture,this function update the 
//dish's description which displays to the customer.
void menu_sys::update_display()
{
	int currentitem_no = IVdishlist->index(IVdishlist->currentItem());
	QString pic_path = g_pic_path+dishes[currentitem_no]->getPicname()+tr(".png");

	TVname->setText(dishes[currentitem_no]->getName());
	TVtype->setText(dishes[currentitem_no]->getType());
	TVfeature->setText(dishes[currentitem_no]->getFeature());
	TVmix->setText(dishes[currentitem_no]->getMix());
	IVpicture->firstItem()->setPixmap(QPixmap(pic_path,"png"));
	//set the text of picture
	QCString yuan = "￥";
	QString dis_text =
			dishes[currentitem_no]->getName()	//name of the dish
			+tr("\n")+pcodec->toUnicode(yuan)	//output '￥'
			+tr("%1").arg((double)(dishes[currentitem_no]->getPrice()),0,'f',2);//price of the dish
	IVpicture->firstItem()->setText(dis_text);
}

//when the customer order a dish,this function update var selected,var total_price,
//the list box showing the selected list and the text box showing the total price
//according to the picture of dishes which customer selects
void menu_sys::update_selected()
{
	//add code here
	int i;
	QString the_order;
	QIconViewItem * QI;
	QI=IVdishlist->currentItem () ;
	int here=IVdishlist->index(QI);

	//judge if this dish has ordered
	for(i=0;i<(int)selected.size();i++)
	{
		if(selected[i] == here)
			break;
	}
	if(i == (int)selected.size())//has not ordered
	{	//insert the index of the dish to vector selected
		selected.push_back(here);
		the_order=tr("%1").arg(dishes[here]->getNo())	//the number of a dish
					+tr("  ")+dishes[here]->getName()	//the name of a dish
					+tr("  ")+dishes[here]->getType()	//the type of a dish
					+tr("  %1").arg((double)(dishes[here]->getPrice()),0,'f',2);//the price of a dish
		LBselected->insertItem(the_order);
		//update the text of TVtotalprice
		total_price+=dishes[here]->getPrice();
		TVtotalprice->setText(tr("%1").arg((double)total_price,0,'f',2));
	}
}

//when the customer clict the delete button,this function remove the
//dish selected in the selected list from var selected and update the
//list box showing the selected list.
void menu_sys::delete_selected()
{
	int index,no;
	QString strSelected;
	vector<int>::iterator iter;

	//nothing is selected
	if(LBselected->currentItem() == -1)
		return;

	//get the index of the dish in vector dishes
	strSelected = LBselected->currentText();
	no = strSelected.left(strSelected.find(' ')).toInt();
	index = dish_index(no);
	//if dish number doesn't exist
	if(index == -1)
	{
		messagebox("删除已选菜时发生错误\ndish no doesn't exist");
		return;
	}
	//calculate the new totalprice
	total_price -= dishes[index]->getPrice();
	//update totalprice
	TVtotalprice->setText(tr("%1").arg((double)total_price,0,'f',2));
	//remove item from LBselected
	LBselected->removeItem(LBselected->currentItem());
	//remove this index from var selected
	for(iter=selected.begin();iter!=selected.end();iter++)
	{
		if(*iter == index)
			break;
	}
	if(iter != selected.end())
		selected.erase(iter);
}

//when the customer clict the clear button,this function remove all of
//dishes selected in the selected list from var selected and clear the 
//text in the list box. 
void menu_sys::clear_selected()
{
	total_price = 0;
	TVtotalprice->setText(tr("0.00"));
	selected.resize(0);
	LBselected->clear();
}

//when the customer clict the confirm button,this function send the order information
//to the server.
void menu_sys::confirm()
{
	//add code here
	unsigned char *buf = NULL;
	int i,ret=0;

	//no selected dish
	if(selected.size() == 0)
		return;

	buf = new unsigned char[(int)dishes.size()+1];
	//get desk_no
	buf[0] = (unsigned char)(desk_no);
	//get selected dishes no
	for(i=0;i<(int)selected.size();i++)
		buf[i+1] = (unsigned char)(dishes[selected[i]]->getNo());
	//send data to server
	ret = ptransfer->send(buf,(int)selected.size()+1,false);//echo=true

	if(ret != -1)//if succeed
	{
		clear_selected();
		messagebox("点菜成功");
	}
	else//error occurs
		messagebox("发送点菜信息失败，请重试");

	delete []buf;
}

//close the form
void menu_sys::close()
{
	//add code here
	menu::close();
}
